#include <stdio.h>
#include <assert.h>

#include "sisInterface.h"
#include "sis/sis.h"

static int sisUsed = 0;

extern void init_sis( int );
extern void end_sis();

void sisInit()
{
  if ( sisUsed == 0 )
    init_sis(0);
  sisUsed ++;
}

void sisEnd()
{
  sisUsed --;
  if ( sisUsed == 0 )
    end_sis();
}

void sisNetworkFree( void *netlist )
{
  network_t *nl = (network_t*)netlist;
  network_free( nl );
}

void *sisNetworkDup( void *netlist )
{
  network_t *nl = (network_t*)netlist;
  network_t *nnl = NULL;
  nnl = network_dup( nl );
  return (void*)nnl;
}

void * sisBLIFToNetlist( FILE *fp )
{
  network_t *nl = NULL;
  assert( fp != NULL );
  read_blif( fp, &nl ) ;
  assert( nl != NULL );
  return nl;
}

void sisNetlistToBLIF( void *netlist, FILE *fp )
{
  network_t *nl = (network_t*)netlist;
  assert( fp != NULL );
  write_blif( fp, nl, 0, 0 );
}

int sisNumberLiterals( void *netlist )
{
  network_t *nl = (network_t*)netlist;
  lsGen gen;
  node_t *node;
  int nlits = 0;

  assert( netlist != NULL );
  foreach_node( nl, gen, node ){
    if ( node_type(node) == INTERNAL )
      nlits += node_num_literal( node );
  }

  return nlits;
}

int sisNetlistEquiv( void *netlist1, void *netlist2 )
{
  network_t *nl1 = (network_t*)netlist1;
  network_t *nl2 = (network_t*)netlist2;
  
  // equal numbers of internal nodes
  if ( network_num_internal( nl1 ) != network_num_internal( nl2 ) )
    return 0;

  // equal numbers of literals
  return (sisNumberLiterals( netlist1 ) == sisNumberLiterals( netlist2 ))?
    1: 0;
}

void sisComExecute( void *netlist, const char *cfile )
{
  FILE *fp = NULL;
  network_t *nl = (network_t*)netlist;
  char s[256];
  
  fp = fopen( cfile, "r" );
  assert( fp != NULL );
  while( fgets( s, 256, fp ) != NULL ){
    s[strlen(s)-1] = 0;
    com_execute( &nl, s );
  }
  fclose( fp );
}
